package com.probos.bosnatuur.monitor;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.provider.MediaStore.Images.Media;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View;
import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class ElementPictures extends Activity {
	
	public static final int DELETE_ID = 9;

	private static final int CAMERA_PIC_REQUEST = 1337;
	private static final String TAG = "ElementPictures";
	
	private Context mCtx;
	private Long mElementId;
	
	private GridView mGrid;
	
	public File outputFile;
	
	private ProjectDbAdapter mDbHelper;

	public class thumbNail {
		public String name;
		public Bitmap bmp;
		public int id;
				
		thumbNail(String new_name, Bitmap new_bmp, int new_id) {
			name = new_name;
			bmp = new_bmp;
			id = new_id;
		}
	}
	
    private thumbNail[] thumbNails;

	public void unloadPictures() {
		if (thumbNails != null)
			for (int i = 0; i < thumbNails.length; i++) {
				if (thumbNails[i] != null)
					thumbNails[i].bmp.recycle();
			}
		thumbNails = null;
	}
    
    public thumbNail getPicture(int index) {
            return thumbNails[index];
    }

    public int numPics() {
            return thumbNails.length;
    }

    public static Bitmap optimizeImage(String file) {
        
        Bitmap bm = null;
        
        byte[] buffer = new byte[1024*16];
        BitmapFactory.Options ops = new BitmapFactory.Options();
        ops.inTempStorage = buffer;
        ops.inDither = true;
        ops.inScaled = true;
        ops.inSampleSize = 1;
        boolean error = false;
        
        //keep looping until we can load the image
        do {
                error = false;
                try {
                        // bm = BitmapFactory.decodeFile(file, ops);
                        bm = BitmapFactory.decodeFile(file);
                }
                catch(OutOfMemoryError e) {
                        Log.e(TAG, "Out of memory....attempting to resize");
                        
                        //resize code
                        ops.inSampleSize *= 2;
                        error = true;
                }
        } while(error);
        
        return bm;
	}
	
	public static DisplayMetrics METRICS = new DisplayMetrics();

	public static int dpToPixels(int dp) {
		int pixels =  (int)(dp * (METRICS.densityDpi/160.0f));
		return pixels;
	}
	
    @Override
    protected void onPause() {
    	// saveState();
    	mDbHelper.close();
    	super.onPause();
    }
    
    @Override
    protected void onResume() {
    	super.onResume();
    	mDbHelper.open();
    }
    
	public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    setContentView(R.layout.element_pictures);

	    mDbHelper = new ProjectDbAdapter(this);
        mDbHelper.open();

	    mCtx = this;
	    
	    outputFile = (savedInstanceState == null) ? null : (File) savedInstanceState.getSerializable("outputFile");	    
	    mElementId = (savedInstanceState == null) ? null : (Long) savedInstanceState.getSerializable(ProjectDbAdapter.KEY_ROWID);
        if (mElementId == null) {
        	Bundle extras = getIntent().getExtras();
        	if (extras != null) {
        		if (extras.containsKey(ProjectDbAdapter.KEY_ROWID)) {
        			mElementId = extras.getLong(ProjectDbAdapter.KEY_ROWID);
        		} else {
        			if (extras.containsKey("new_id")) mElementId = extras.getLong("new_id");
        		}
        	}
        }
        
	    Button photoButton = (Button) findViewById(R.id.add_picture);
        photoButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
/*				
				ContentValues values = new ContentValues();
				values.put(Media.TITLE, filename);
				values.put(Media.DESCRIPTION, "Image from Android Emulator");
				outputFileUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
*/            	
            	outputFile = getOutputMediaFile(0);
				Log.i(TAG, "photoButton.onClick outputFile: " + outputFile.getPath());
				
            	Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
            	intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(outputFile));  
            	startActivityForResult(intent, CAMERA_PIC_REQUEST);
        	}
        });
        
        updatePictures();

        mGrid = (GridView) findViewById(R.id.gridview);
        mGrid.setAdapter(new ImageAdapter(this));
        mGrid.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
				Toast.makeText(mCtx, "" + v.getTag(), Toast.LENGTH_SHORT).show();				
			}
	    });
/*
	    gridview.setOnItemLongClickListener(new OnItemLongClickListener() {
			public boolean onItemLongClick(AdapterView<?> parent, View v, int position, long id) {
				// Toast.makeText(ElementPictures.this, "" + position, Toast.LENGTH_SHORT).show();
				return false;				
			}	    	
	    });
*/	    
        mGrid.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {		
	    	public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
		        // super.onCreateContextMenu(menu, v, menuInfo);
		        // menu.add(0, EDIT_ID, 0, R.string.menu_edit);
	    		
		        menu.add(0, DELETE_ID, 0, R.string.menu_delete_picture);
		     }
	    });
	    
	    // this.registerForContextMenu(ImageView)
	    
	}	

	public boolean onContextItemSelected(MenuItem item) {    	
        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
        switch(item.getItemId()) {
            case DELETE_ID:
            	
            	// Toast.makeText(mCtx, "DELETE: "+ info.id, Toast.LENGTH_SHORT).show();
            	// info.position
            	
            	mDbHelper.open();
                mDbHelper.deletePicture(info.id);
                updatePictures();
                
                BaseAdapter b = (BaseAdapter) mGrid.getAdapter();
                b.notifyDataSetChanged();
                
                return true;
//            case EDIT_ID:
//                Intent i = new Intent(this, ProjectEdit.class);
//                i.putExtra(ProjectDbAdapter.KEY_ROWID, info.id);
//                startActivityForResult(i, ACTIVITY_EDIT);
//                return true;                
        }
        return false;
    }			
	
	
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
	    if (requestCode == CAMERA_PIC_REQUEST) {
	    	
			if (resultCode == Activity.RESULT_OK) {
				
				String filename = "?";
				if (outputFile != null) {
					filename = outputFile.getName();
				}
				Log.i(TAG, "onActivityResult:" + filename);
				
				mDbHelper.open();
				mDbHelper.insertPicture(mElementId, filename, null);
				
				updatePictures();
                BaseAdapter b = (BaseAdapter) mGrid.getAdapter();
                b.notifyDataSetChanged();				
			}
	    }
	}
	
	protected void updatePictures() {
		Cursor c = mDbHelper.getPictures(mElementId);
   		if (c != null) {
   			
   			int aantal = c.getCount();
   			int i = 0;
   			
   			Log.i(TAG, "updatePictures: " + aantal);
   			
     	    File picsDir = new File(Environment.getExternalStoragePublicDirectory(
	              Environment.DIRECTORY_PICTURES), "BosNatuurMonitor");
     	    
   	     	File thumbsDir = new File(picsDir, "thumbnails");  	     	
   		    if (! thumbsDir.exists()){
   		        if (! thumbsDir.mkdirs()){
   		            Log.d(TAG, "Failed to create directory");
   		        }
   		    }
   			
   			if (aantal > 0) {
   				thumbNails = new thumbNail[aantal];
   				   				  				
   	  			while(c.moveToNext()) {			
   	   				int row_id = c.getInt(c.getColumnIndexOrThrow(ProjectDbAdapter.KEY_ROWID));
   	       			String filename = c.getString(c.getColumnIndexOrThrow(ProjectDbAdapter.KEY_NAME));
   	       			String tekst = c.getString(c.getColumnIndexOrThrow(ProjectDbAdapter.KEY_DESCRIPTION));
   	       			
	   	     	    File f;
	   	     	    if (filename.startsWith(picsDir.getPath())) {
	   	     	    	f = new File(filename);
	   	     	    } else {
	   	     	    	f = new File(picsDir,filename);
	   	     	    }
	   	     	    
					File thumbFile = new File(thumbsDir,"tn_" + f.getName());
					
					if (thumbFile.exists()) {
						Bitmap thumb = BitmapFactory.decodeFile(thumbFile.getPath());
						thumbNails[i] = new thumbNail(filename, thumb, row_id);
						i++;
					} else {
   	       			
	   	       			if (f.exists()) {
							try {
								Log.i(TAG, "updatePictures(" + i + ") : " + f.getName());
								Bitmap bmp = BitmapFactory.decodeFile(f.getPath());
								Bitmap thumb = ThumbnailUtils.extractThumbnail(bmp,96,96);
								thumbNails[i] = new thumbNail(filename, thumb, row_id);
								
								try {
								       FileOutputStream out = new FileOutputStream(thumbFile.getPath());
								       thumb.compress(Bitmap.CompressFormat.JPEG, 90, out);
								} catch (Exception e) {
								       e.printStackTrace();
								}
								
								i++;
							} catch (OutOfMemoryError e) {
								Log.e(TAG, "Images are too big, out of memory");
							}						
	   	       			} else {
	   	       				Log.d(TAG, "File not found: " + filename );
	   	       			}
	   	       			
					}
   	       			
   	  			}
   			} else {
   				unloadPictures();
   			}
   		}
	}
	
	protected void onSaveInstanceState (Bundle outState) {
		outState.putSerializable("outputFile", outputFile);
	}
	
	private File getTempFile(Context context) {
		// it will return /sdcard/image.tmp
		final File path = new File(Environment.getExternalStorageDirectory(),
				context.getPackageName());
		if (!path.exists()) {
			path.mkdir();
		}

//		SimpleDateFormat timeStampFormat = new SimpleDateFormat("yyyyMMddHHmmssSS");
//		String filename = timeStampFormat.format(new Date());				
//		Log.i(TAG, "getTempFile filename: " + filename);
		
		return new File(path, "image.tmp");
	}
	
	/** Create a file Uri for saving an image or video */
	private static Uri getOutputMediaFileUri(int type){
	      return Uri.fromFile(getOutputMediaFile(type));
	}

	/** Create a File for saving an image or video */
	private static File getOutputMediaFile(int type){
	    // To be safe, you should check that the SDCard is mounted
	    // using Environment.getExternalStorageState() before doing this.

	    File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
	              Environment.DIRECTORY_PICTURES), "BosNatuurMonitor");
	    // This location works best if you want the created images to be shared
	    // between applications and persist after your app has been uninstalled.

	    // Create the storage directory if it does not exist
	    if (! mediaStorageDir.exists()){
	        if (! mediaStorageDir.mkdirs()){
	            Log.d(TAG, "Failed to create directory");
	            return null;
	        }
	    }

	    // Create a media file name
	    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
	    File mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg");

	    return mediaFile;
	}	

    @Override     
    protected void onDestroy() {
    	unloadPictures();
        mDbHelper.close();
        super.onDestroy();
    }
    
	public class ImageAdapter extends BaseAdapter {
	    private Context mContext;

	    public ImageAdapter(Context c) {
	        mContext = c;
	    }

		public int getCount() {
			// TODO Auto-generated method stub
			if (thumbNails == null) {
				return 0;
			} else {
				return thumbNails.length;
			}
		}

		public Object getItem(int arg0) {
			// TODO Auto-generated method stub
			return thumbNails[arg0];
		}

		public long getItemId(int arg0) {
			// TODO Auto-generated method stub
			return thumbNails[arg0].id;
		}

	    // create a new ImageView for each item referenced by the Adapter
	    public View getView(int position, View convertView, ViewGroup parent) {
	        ImageView imageView;
	        if (convertView == null) {  // if it's not recycled, initialize some attributes
	            imageView = new ImageView(mContext);
	            imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
	            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
	            imageView.setPadding(8, 8, 8, 8);
	        } else {
	            imageView = (ImageView) convertView;
	        }
	        if (position<thumbNails.length) {
		        imageView.setImageBitmap(thumbNails[position].bmp);
		        imageView.setTag(thumbNails[position].name);
	        } else {
	        	Log.d(TAG, "Position: "+position+ " not found");
	        }
	        
	        return imageView;
	    }
	}    
}
